package com.jh.paymentchannel.service;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import cn.jh.common.tools.Base64;
import cn.jh.common.tools.Log;
import cn.jh.common.tools.rsa.Signatory;

import com.jh.paymentchannel.util.Util;
import com.jh.paymentchannel.util.YiLianKeyConstants;


@Controller
@EnableAutoConfiguration
public class YiLianCallBackService {

	private static final Logger log = LoggerFactory.getLogger(YiLianCallBackService.class);
	
	@Autowired
	Util util;
	
	@RequestMapping(method=RequestMethod.POST,value="/v1.0/paymentchannel/topup/yilian/return_call")
	public String returnCall(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException{
		
		// 设置编码
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		// 结果通知参数，易联异步通知采用GET提交
		String version = request.getParameter("Version");
		String merchantId = request.getParameter("MerchantId");
		String merchOrderId = request.getParameter("MerchOrderId");
		String amount = request.getParameter("Amount");
		String extData = request.getParameter("ExtData");
		String orderId = request.getParameter("OrderId");
		String status = request.getParameter("Status");
		String payTime = request.getParameter("PayTime");
		String settleDate = request.getParameter("SettleDate");
		String sign = request.getParameter("Sign");

		
		String retMsgJson = "";
		String message = "";
		try {
			Log.setLogFlag(true);
			Log.println("---交易： 订单结果异步通知-------------------------");
			//验证订单结果通知的签名
			boolean b = bCheckNotifySign(version, merchantId, merchOrderId, 
					amount, extData, orderId, status, payTime, settleDate, sign, 
					YiLianKeyConstants.YILIAN_PUB_KEY_PRIVATE);
			if (!b) {
				retMsgJson = "{\"RetCode\":\"E101\",\"RetMsg\":\"验证签名失败!\"}";
				Log.println("验证签名失败!");
				message = "验证签名失败!";
			}else{
		
				if ("02".equals(status)) { // 订单已支付;
				
					retMsgJson = "{\"RetCode\":\"0000\",\"RetMsg\":\"订单已支付\"}";
					Log.println("订单已支付!");
					message = "订单已支付!";
					return "redirect:http://1.xinli2017.applinzi.com/login/zhufucg.html";
				} else {
					retMsgJson = "{\"RetCode\":\"E102\",\"RetMsg\":\"订单支付失败+"+status+"\"}";
					Log.println("订单支付失败!status="+status);
					message = "订单支付失败!";
					
				}
			}
		} catch (Exception e) {
			retMsgJson = "{\"RetCode\":\"E103\",\"RetMsg\":\"处理通知结果异常\"}";
//			System.out.println("处理通知结果异常!e="+e.getMessage());
			message = "处理通知结果异常!";
		}
		Log.println("-----处理完成----");
		//返回数据
	   /* PrintWriter out = response.getWriter();
	    out.println(retMsgJson);
	    out.close(); // for HTTP1.1
*/	    
		model.addAttribute("message", message);
		
		return "redirect:http://1.xinli2017.applinzi.com/login/zhufusb.html";
		
	    
	    
	}
	
	
	
	@RequestMapping(method=RequestMethod.POST,value="/v1.0/paymentchannel/topup/yilian/notify_call")
	public @ResponseBody Object notifyCall(HttpServletRequest request, HttpServletResponse response) throws IOException{
		
		        log.info("yilian  callback  ===========");
		
		
				// 设置编码
				request.setCharacterEncoding("utf-8");
				response.setCharacterEncoding("utf-8");
				response.setContentType("text/html;charset=utf-8");

				// 结果通知参数，易联异步通知采用GET提交
				String version = request.getParameter("Version");
				String merchantId = request.getParameter("MerchantId");
				String merchOrderId = request.getParameter("MerchOrderId");
				String amount = request.getParameter("Amount");
				String extData = request.getParameter("ExtData");
				String orderId = request.getParameter("OrderId");
				String status = request.getParameter("Status");
				String payTime = request.getParameter("PayTime");
				String settleDate = request.getParameter("SettleDate");
				String sign = request.getParameter("Sign");

				// 需要对必要输入的参数进行检查，本处省略...
				// 订单结果逻辑处理
				String retMsgJson = "";
				try {
					Log.setLogFlag(true);
					Log.println("---交易： 订单结果异步通知-------------------------");
					//验证订单结果通知的签名
					boolean b = bCheckNotifySign(version, merchantId, merchOrderId, 
							amount, extData, orderId, status, payTime, settleDate, sign, 
							YiLianKeyConstants.YILIAN_PUB_KEY_PRIVATE);
					if (!b) {
						retMsgJson = "{\"RetCode\":\"E101\",\"RetMsg\":\"验证签名失败!\"}";
						Log.println("验证签名失败!");
					}else{
						// 签名验证成功后，需要对订单进行后续处理
						
						if ("02".equals(status)) { // 订单已支付;
							
							
							//if ("0000".equals(status)) { // 若是互联金融行业, 订单已支付的状态为【0000】
							// 1、检查Amount和商户系统的订单金额是否一致
							// 2、订单支付成功的业务逻辑处理请在本处增加（订单通知可能存在多次通知的情况，需要做多次通知的兼容处理）；
							// 3、返回响应内容
							
							
							/**更新订单状态*/
							/**调用下单，需要得到用户的订单信息*/
							RestTemplate restTemplate=new RestTemplate();
							
							URI uri = util.getServiceUrl("transactionclear", "error url request!");
							String url = uri.toString() + "/v1.0/transactionclear/payment/update";
							
							/**根据的用户手机号码查询用户的基本信息*/
							MultiValueMap<String, String> requestEntity  = new LinkedMultiValueMap<String, String>();
							requestEntity.add("status", "1");
							requestEntity.add("order_code",  merchOrderId);
							String result = restTemplate.postForObject(url, requestEntity, String.class);
							
							/**判断是否有外放的通道的处理， 如果有那么继续回调外放哦*/
							uri = util.getServiceUrl("transactionclear", "error url request!");
							url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
							
							
							requestEntity  = new LinkedMultiValueMap<String, String>();
							requestEntity.add("order_code",  merchOrderId);
							result = restTemplate.postForObject(url, requestEntity, String.class);
							
							JSONObject jsonObject =  JSONObject.fromObject(result);
							JSONObject resultObj  =  jsonObject.getJSONObject("result");
							String outMerOrdercode  =  resultObj.getString("outMerOrdercode");
							String orderdesc        =  resultObj.getString("desc");
							String phone            =  resultObj.getString("phone");
							String  tranamount      =  resultObj.getString("amount");
							String channelTag       =  resultObj.getString("channelTag");
							String notifyURL        =  resultObj.getString("outNotifyUrl");
							if(outMerOrdercode != null && !outMerOrdercode.equalsIgnoreCase("")){
								uri = util.getServiceUrl("channel", "error url request!");
								url = uri.toString() + "/v1.0/channel/callback/yilian/notify_call";
								requestEntity  = new LinkedMultiValueMap<String, String>();
								requestEntity.add("merchant_no",  phone);
								requestEntity.add("amount",  tranamount);
								requestEntity.add("channel_tag",  channelTag);
								requestEntity.add("order_desc",  URLEncoder.encode(orderdesc, "UTF-8"));
								requestEntity.add("order_code",  outMerOrdercode);
								requestEntity.add("sys_order",  merchOrderId);
								requestEntity.add("notify_url", URLEncoder.encode(notifyURL, "UTF-8"));
								result = restTemplate.postForObject(url, requestEntity, String.class);
							}

							
							retMsgJson = "{\"RetCode\":\"0000\",\"RetMsg\":\"订单已支付\"}";
							Log.println("订单已支付!");
						} else {
							// 1、订单支付失败的业务逻辑处理请在本处增加（订单通知可能存在多次通知的情况，需要做多次通知的兼容处理，避免成功后又修改为失败）；
							// 2、返回响应内容
							retMsgJson = "{\"RetCode\":\"E102\",\"RetMsg\":\"订单支付失败+"+status+"\"}";
							Log.println("订单支付失败!status="+status);
						}
					}
				} catch (Exception e) {
					retMsgJson = "{\"RetCode\":\"E103\",\"RetMsg\":\"处理通知结果异常\"}";
//					System.out.println("处理通知结果异常!e="+e.getMessage());
				}
				Log.println("-----处理完成----");
				//返回数据
			    PrintWriter out = response.getWriter();
			    out.println(retMsgJson);
			    out.close(); // for HTTP1.1
			    return null;
	}
	
	
	/**
	 * 验证订单结果通知签名
	 * @param version       ： 通讯版本号
	 * @param merchantId    ： 商户代码
	 * @param merchOrderId  ：商户订单号
	 * @param amount		： 商户订单金额
	 * @param extData		：商户保留信息； 通知结果时，原样返回给商户；字符最大128，中文最多40个；参与签名：采用UTF-8编码 ； 提交参数：采用UTF-8的base64格式编码
	 * @param orderId		：易联订单号
	 * @param status		：订单状态
	 * @param payTime		：订单支付时间
	 * @param settleDate	：订单结算日期
	 * @param sign			：签名数据
	 * @param pubKey		：易联签名验证公钥
	 * @return				： true：验证通过； false：验证不通过
	 * @throws Exception
	 */
	public static boolean bCheckNotifySign(String version, String merchantId, 
			String merchOrderId, String amount, String extData, String orderId, 
			String status, String payTime, String settleDate, String sign,
			String pubKey) 
			throws Exception{
		// 对extData进行转码处理: base64转码
		if (extData != null) {
			extData = extData.replaceAll(" ", "+");
			extData = new String(Base64.decode(extData), YiLianKeyConstants.PAYECO_DATA_ENCODE);
			Log.println("extData=" + extData); // 日志输出，检查转码是否正确
		}
		 
		// 进行数据签名
		String data = "Version=" + version + "&MerchantId=" + merchantId
				+ "&MerchOrderId=" + merchOrderId + "&Amount=" + amount
				+ "&ExtData=" + extData + "&OrderId=" + orderId + "&Status="
				+ status + "&PayTime=" + payTime + "&SettleDate=" + settleDate;

		// 验证签名
		sign = sign.replaceAll(" ", "+");
		
		log.info("YILIAN CALLBACK  RESULT = "+data);
		
		boolean b = Signatory.verify(pubKey, data, sign, YiLianKeyConstants.PAYECO_DATA_ENCODE);
		Log.println("PublicKey=" + pubKey);
		Log.println("data=" + data);
		Log.println("Sign=" + sign);
		Log.println("验证结果=" + b);
		return b;
	}
	
}
